/*
 * @(#)Xfvhdl.java        3.0                                 2004/09/14
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//			HERRAMIENTA DE S�NTESIS: XFVHDL3	 			    
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

package xfuzzy.xfvhdl;

import xfuzzy.*;
import xfuzzy.lang.*;
import java.io.*;

/**
* Clase principal de la herramienta de s�ntesis de sistemas
* difusos Xfvhdl3.
* @author Jos� Mar�a �vila Maireles, <b>e-mail</b>: josavimai@alum.us.es
* @version 3.0
*/
public class Xfvhdl {

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //		  ATRIBUTOS DE LA CLASE 				       
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

   public static Xfuzzy xfuzzy = null;
   private XfvhdlIDefuzzification defuzzification;
   private XfvhdlIFactoryDefuzzification factory_defuzzification;
   private XfvhdlPrjFile prjFile = new XfvhdlPrjFile();
   XfvhdlMessage msg = new XfvhdlMessage(xfuzzy);

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //			    CONSTRUCTOR DE LA CLASE					 	   
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

   public Xfvhdl(Specification spec) throws IOException {

      // Cargo el Deffuzificador
      factory_defuzzification = XfvhdlDefuzzificationFactory.getInstance();
      defuzzification =
         factory_defuzzification.create(
            XfvhdlProperties.defuzzification_type);

      // Dependiendo del m�todo de defuzzificaci�n se calcular�n los 
      // pesos de las funciones de pertenencia.
      if (XfvhdlProperties
         .defuzzification_type
         .equalsIgnoreCase("WeightedFuzzyMean")
         || XfvhdlProperties.defuzzification_type.equalsIgnoreCase(
            "THIRD_SIMPLIED_METHOD")) {
         XfvhdlProperties.calculateWeights = true;
      }

      // Creo un objeto error por si ocurren, y como estado inicial, 
      // correcto
      XfvhdlError error = new XfvhdlError();
      String state = new String("Done");

      // Activo el log si estoy ejecutando desde la ventana gr�fica
      if (XfvhdlProperties.inWindow == true)
         msg.setXfuzzy(xfuzzy);

      // ****************************************************************   
      // ********* Creando el fichero Constants.vhdl ********************
      // ****************************************************************
      // *** Este fichero se genera siempre, independientemente de la 
      // *** opci�n elegida para implementar la memoria.	            
      // ****************************************************************
      msg.addMessage(
         "\n>>>> Generating file:  "
            + XfvhdlProperties.outputFile
            + "Constants.vhdl");
      msg.show();
      XfvhdlConstantsFile constants = new XfvhdlConstantsFile();
      // Calculo las constantes que formar�n el fichero Constants.vhdl.
      constants.calculateConstants(spec, defuzzification);
      // Creo el fichero Constants.vhdl.
      new XfvhdlCreateFile(
         XfvhdlProperties.outputFile + "Constants.vhdl",
         constants.createConstantsSource());
      prjFile.addFile(XfvhdlProperties.outputFile + "Constants.vhdl");
      if (error.hasErrors())
         state = "With error";
      msg.addMessage("     ......... " + state);
      msg.show();
      // ********* !! Fichero Constants.vhdl creado �� ******************

      // ****************************************************************   
      // ********* Creando el fichero Entities.vhdl *********************
      // ****************************************************************
      // *** Este fichero se genera siempre, independientemente de la 
      // *** opci�n elegida para implementar la memoria.	            
      // ****************************************************************
      msg.addMessage(
         "\n>>>> Generating file:  "
            + XfvhdlProperties.outputFile
            + "Entities.vhdl");
      msg.show();
      XfvhdlEntitiesFile entities = new XfvhdlEntitiesFile(prjFile);
      // Creo el fichero Entities.vhdl.
      new XfvhdlCreateFile(
         XfvhdlProperties.outputFile + "Entities.vhdl",
         entities.createEntitiesSource(defuzzification));
      prjFile.addFile(XfvhdlProperties.outputFile + "Entities.vhdl");
      if (error.hasErrors())
         state = "With error";
      msg.addMessage("     ......... " + state);
      msg.show();
      // ********* !! Fichero Entities.vhdl creado �� ******************

      if (XfvhdlProperties.calcArithmetic == false) {
         // LOS MFCs VAN EN MEMORIA
         // La memoria de antecedentes s�lo se crea si la opci�n de 
         // implementaci�n es en ROM o con L�gica Combinacional
         if (XfvhdlProperties.memoryType.equals((String) "ROM")
            || XfvhdlProperties.memoryType.equals(
               (String) "Combinational Logic")) {
            // ********************************************************
            // ************ Creando la memoria de antecedentes ********
            // ********************************************************
            // ***  Estos ficheros S�LO se generan si los MFC's van en       
            // ***  memoria ROM o con L�gica Combinacional.                  
            // ********************************************************
            XfvhdlAntecedentMemFiles antecedentMemFiles =
               new XfvhdlAntecedentMemFiles(prjFile, xfuzzy);
            antecedentMemFiles.createAntecedentsMemory(spec);
            // Generamos los ficheros complementarios con el contenido 
            // de la memoria de antecedentes, si se ha indicado la 
            // generaci�n de archivos complementarios. 
            if (XfvhdlProperties.complementaryFiles == true) {
               XfvhdlAntecedentMemComplementaryFiles amcf =
                  new XfvhdlAntecedentMemComplementaryFiles();
               amcf.createCF(spec);
            }
            // ********* !! Ficheros AntecedentMem_x.vhdl creados �� **
         } else {
            // Para los casos de RAM Block y RAM Distributed, s�lo es 
            // necesario generar los ficheros complementarios, en caso 
            // de que as� se haya indicado
            if (XfvhdlProperties.complementaryFiles == true) {
               msg.addMessage(
                  "\n>>>> Generating antecedent memory's "
                     + "complementary files ");
               msg.show();
               XfvhdlAntecedentMemComplementaryFiles amcf =
                  new XfvhdlAntecedentMemComplementaryFiles();
               amcf.createCF(spec);
               if (error.hasErrors())
                  state = "With error";
               msg.addMessage("     ......... " + state);
               msg.show();
            }
         }
      } else {
         // LOS MFCs SON DE C�LCULO ARITM�TICO
         // La memoria de c�lculo aritm�tico s�lo se crea si la opci�n 
         // de implementaci�n es en ROM o con L�gica Combinacional
         if (XfvhdlProperties.memoryType.equals((String) "ROM")
            || XfvhdlProperties.memoryType.equals(
               (String) "Combinational Logic")) {
            // *********************************************************
            // ********* Creando la memoria de c�lculo aritm�tico ******
            // *********************************************************
            // ***  Estos ficheros S�LO se generan si los MFC's son de      
            // ***  c�lculo aritm�tico y con memoria ROM o                  
            // ***  L�gica Combinacional.                                   			
            // *********************************************************
            XfvhdlArithCalcMemFiles arithCalcMemFiles =
               new XfvhdlArithCalcMemFiles(prjFile, xfuzzy);
            arithCalcMemFiles.createArithCalcMem(spec);
            // ********* !! Fichero ArithCalcMem.vhdl creado �� ********
         }
      }

      // ****************************************************************	
      // ************** Creando la memoria de reglas ********************
      // ****************************************************************
      // ***  Estos ficheros S�LO se generan si se usa memoria ROM    
      // ***  o L�gica Combinacional.                                 			
      // ****************************************************************
      if (XfvhdlProperties.memoryType.equals((String) "ROM")
         || XfvhdlProperties.memoryType.equals(
            (String) "Combinational Logic")) {
         msg.addMessage(
            "\n>>>> Generating file:  "
               + XfvhdlProperties.outputFile
               + "RulesMem.vhdl");
         msg.show();
         XfvhdlIRulesMem rulesMem;
         // La memoria de reglas depende del parametro "-inROM" 
         if (XfvhdlProperties.rulesMemWithROM)
            rulesMem = new XfvhdlRulesMemFileWithROM();
         else
            rulesMem = new XfvhdlRulesMemFile();
         // Creo el fichero RulesMem.vhdl.
         new XfvhdlCreateFile(
            XfvhdlProperties.outputFile + "RulesMem.vhdl",
            rulesMem.createRulesMemSource(spec));
         prjFile.addFile(XfvhdlProperties.outputFile + "RulesMem.vhdl");
         if (error.hasErrors())
            state = "With error";
         // Generamos los ficheros complementarios con el contenido de la 
         // memoria de reglas, si se ha indicado la generaci�n de 
         // archivos complementarios. 
         if (XfvhdlProperties.complementaryFiles == true) {
            XfvhdlRulesMemComplementaryFile rmcf =
               new XfvhdlRulesMemComplementaryFile();
            rmcf.createCF(spec);
            msg.addMessage(
               "  (with complementary files)     ......... " + state);
            msg.show();
         } else {
            msg.addMessage("     ......... " + state);
            msg.show();
         }
         // ********* !! Fichero RulesMem.vhdl creado �� ****************
      } else {
         // Para los casos de RAM Block y RAM Distributed, s�lo es 
         // necesario generar los ficheros complementarios, en caso de 
         // que as� se haya indicado
         if (XfvhdlProperties.complementaryFiles == true) {
            msg.addMessage(
               "\n>>>> Generating rules memory's "
                  + "complementary files ");
            msg.show();
            XfvhdlRulesMemComplementaryFile rmcf =
               new XfvhdlRulesMemComplementaryFile();
            rmcf.createCF(spec);
            if (error.hasErrors())
               state = "With error";
            msg.addMessage("     ......... " + state);
            msg.show();
         }
      }

      // ****************************************************************	
      // ******* Creando el c�digo VHDL del controlador difuso **********
      // ****************************************************************
      // *** Este fichero se genera siempre, independientemente de la 
      // *** opci�n elegida para implementar la memoria.	            
      // ****************************************************************
      msg.addMessage(
         "\n>>>> Generating file:  "
            + XfvhdlProperties.outputFile
            + ".vhdl");
      msg.show();
      XfvhdlOutputFlcFile FlcFile = new XfvhdlOutputFlcFile();
      // Creo el fichero outputFile.vhdl. (por defecto FLC.vhdl).
      new XfvhdlCreateFile(
         XfvhdlProperties.outputFile + ".vhdl",
         FlcFile.createOutputFlcSource(spec, defuzzification));
      prjFile.addFile(XfvhdlProperties.outputFile + ".vhdl");
      if (error.hasErrors())
         state = "With error";
      msg.addMessage("     ......... " + state);
      msg.show();
      // ********* !! Fichero outputFile.vhdl creado �� *****************

      // ****************************************************************
      // ************** Creando el testbench ****************************
      // ****************************************************************
      // *** Este fichero se genera siempre, independientemente de la 
      // *** opci�n elegida para implementar la memoria.	            
      // ****************************************************************
      msg.addMessage(
         "\n>>>> Generating file:  "
            + XfvhdlProperties.outputFile
            + "TestBench.vhdl");
      msg.show();
      XfvhdlTestBenchFile TestBenchFile = new XfvhdlTestBenchFile();
      // Creo el fichero TestBench.vhdl.
      new XfvhdlCreateFile(
         XfvhdlProperties.outputFile + "TestBench.vhdl",
         TestBenchFile.createTestBenchSource(spec));
      // Este fichero no es sintetizable, as� q no lo incluimos en el .prj
      // prjFile.addFile(XfvhdlProperties.outputFile + "TestBench.vhdl");
      if (error.hasErrors())
         state = "With error";
      msg.addMessage("     ......... " + state);
      msg.show();
      // ********* !! Fichero TestBench.vhdl creado �� ******************

      // ****************************************************************
      // ************** Creando el fichero prj **************************
      // ****************************************************************
      // *** Este fichero se genera cuando la herramienta de s�ntesis 
      // *** es Xilinx XST.	                                        
      // ****************************************************************
      if (XfvhdlProperties.synthesisTool.equals((String) "XILINX_XST")) {
         msg.addMessage(
            "\n>>>> Generating file:  "
               + XfvhdlProperties.outputFile
               + ".prj");
         msg.show();
         // Creo el fichero .prj.
         new XfvhdlCreateFile(
            XfvhdlProperties.outputFile + ".prj",
            prjFile.getPrj());
         if (error.hasErrors())
            state = "With error";
         msg.addMessage("     ......... " + state);
         msg.show();
      }
      // ************* !! Fichero .prj creado �� ************************	 

      // ****************************************************************
      // ************** Creando el fichero de script XST ****************
      // ****************************************************************
      // *** Este fichero se genera cuando la herramienta de s�ntesis 
      // *** es Xilinx XST.	                                        
      // ****************************************************************
      if (XfvhdlProperties.synthesisTool.equals((String) "XILINX_XST")) {
         msg.addMessage(
            "\n>>>> Generating file:  "
               + XfvhdlProperties.outputFile
               + "Script.xst");
         msg.show();
         XfvhdlScriptXstFile ScriptXstFile = new XfvhdlScriptXstFile();
         // Creo el fichero de script.
         new XfvhdlCreateFile(
            XfvhdlProperties.outputFile + "Script.xst",
            ScriptXstFile.createScriptXstSource());
         if (error.hasErrors())
            state = "With error";
         msg.addMessage("     ......... " + state);
         msg.show();
      }
      // ************* !! Fichero de script XST  creado �� **************	 

      // ****************************************************************
      // ************** Creando el fichero de script FST ****************
      // ****************************************************************
      // *** Este fichero se genera cuando la herramienta de s�ntesis 
      // *** es una de las herramientas de synopsys.	                
      // ****************************************************************
      if (XfvhdlProperties.synthesisTool.equals((String) "FPGA_Express")
         || XfvhdlProperties.synthesisTool.equals(
            (String) "FPGA_Compiler_2")) {
         msg.addMessage(
            "\n>>>> Generating file:  "
               + XfvhdlProperties.outputFile
               + "Script.fst");
         msg.show();
         XfvhdlScriptFile ScriptFile = new XfvhdlScriptFile();
         // Creo el fichero de script.
         new XfvhdlCreateFile(
            XfvhdlProperties.outputFile + "Script.fst",
            ScriptFile.createScriptSource());
         if (error.hasErrors())
            state = "With error";
         msg.addMessage("     ......... " + state);
         msg.show();
      }
      // ************* !! Fichero de script FST  creado �� **************	 		 
   }

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //		FUNCION PRINCIPAL DE LA APLICACION					    
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

   public static void main(String args[]) throws IOException {

      // Trato los par�metros que me pasan desde la l�nea de comandos.
      XfvhdlParameter param = new XfvhdlParameter(args);
      param.loadParameter();

      // Leo el fichero XFL y le paso el parser.	   
      XflParser xflparser = new XflParser();
      XfvhdlMessage msg2 = new XfvhdlMessage(xfuzzy);
      msg2.addMessage(">>>> File Syntax Analysis.");
      msg2.show();
      Specification spec = xflparser.parse(XfvhdlProperties.ficheroXFL);
      if (spec == null) {
         msg2.addMessage(xflparser.resume());
         XfvhdlError err = new XfvhdlError(1);
         err.show();
         return;
      }
      msg2.addMessage("        Correct File Syntax.\n");
      msg2.show();

      // A partir de aqui depende si la aplicaci�n se ejecuta desde la 
      // consola o desde una ventana.
      if (XfvhdlProperties.inWindow == false) {
         // EJECUTAMOS DESDE LA CONSOLA
         inConsoleExecution(spec,null);
      } else {
         // EJECUTAMOS DESDE UNA VENTANA
         XfvhdlWindow window = new XfvhdlWindow(null);
         window.setVisible(true);
      }
   }

   public static void inConsoleExecution(Specification spec,String args[])
      throws IOException {

      // Aunque estamos dentro de la ejecuci�n desde consola, en verdad,
      // este m�todo se ejecuta siempre,la diferencia es que si antes hemos
      // mostrado la ventana gr�fica, ahora hay que leer los par�metros
      // que se nos pasan desde ella.
      /*
      if (XfvhdlProperties.inWindow == true) {
         XfvhdlParameter param = new XfvhdlParameter(args);
         param.loadParameter();
      }
      */

      XfvhdlMessage msg2 = new XfvhdlMessage(xfuzzy);

      // Sacamos la informaci�n necesaria del conjunto de operadores,
      // tales como el m�todo de defuzzificaci�n y la operaci�n AND.
      Operatorset[] opset = spec.getOperatorsets();
      String opAnd = opset[0].and.getFunctionName();
      String defuzMethod = opset[0].defuz.getFunctionName();
      if (opAnd.equalsIgnoreCase("min") || opAnd.equalsIgnoreCase("prod"))
         XfvhdlProperties.operationAnd = opAnd;
      else {
         XfvhdlError err = new XfvhdlError();
         err.newWarning(28);
      }
      XfvhdlProperties.defuzzification_type = defuzMethod;

      // Llamo al constructor de la clase con la espeficicaci�n del sistema
      new Xfvhdl(spec);

      // Mostramos por pantalla los errores que se han producido
      XfvhdlError error = new XfvhdlError();
      error.show();

      // Lanzamos la herramienta de s�ntesis -si procede-
      if (XfvhdlProperties.synthesis == true) {
         //No puede haber errores
         if (error.hasErrors()) {
            XfvhdlError err4 = new XfvhdlError(24);
            err4.show();
            return;
         }

         String command1 = new String();

         //Depende de la herramienta que se haya indicado
         if (XfvhdlProperties
            .synthesisTool
            .equals((String) "XILINX_XST")) {
            // Creo una cadena con la ruta del directorio q necesitamos
            // crear, y luego lo creamos
            String hola =
               new String(
                  ""
                     + XfvhdlProperties.outputDirectory
                     + XfvhdlProperties.outputFile
                     + "_synthesis");
            File temp = new File(hola);
            temp.mkdirs();

            msg2.addMessage("\n\n>>>> Running Xilinx XST\n");
            command1 =
               "xst -ifn "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + "Script.xst -ofn "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + ".log";

         } else if (
            XfvhdlProperties.synthesisTool.equals(
               (String) "FPGA_Express")) {
            msg2.addMessage("\n\n>>>> Running Synopsys FPGA Express\n");
            command1 =
               "fe_shell -oem xilinx -f "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + "Script.fst";
         } else if (
            XfvhdlProperties.synthesisTool.equals(
               (String) "FPGA_Compiler_2")) {
            msg2.addMessage("\n\n>>>> Running Synopsys FPGA Compiler 2\n");
            command1 =
               "fc2_shell -f "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + "Script.fst | tee "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + ".log";
         } else {
            XfvhdlError err5 = new XfvhdlError(0);
            err5.show();
            return;
         }

         //Mostramos un mensaje de informaci�n
         msg2.show();

         // El siguiente bloque comentado lo que hac�a era ejecutar
         // la herramienta externa, �pero sin mostrar la salida de
         // dicha herramienta por pantalla.
         /*
         	//Ejecutamos la herramienta externa
         	Runtime obj = Runtime.getRuntime();
         
         	try {
         		msg2.addMessage("\n Executing...<" + command1 + ">");
         		msg2.show();
         		obj.exec(command1);
         	} catch (Exception e) {
         		XfvhdlError err5 = new XfvhdlError(25);
         		err5.show();
         		return;
         	}
         */

         // Ejecutamos la herramienta externa, mostrando por pantalla
         // la salida de dicha herramienta.
         try {
            String line;
            msg2.addMessage("\n Executing...<" + command1 + ">");
            msg2.show();
            Process p = Runtime.getRuntime().exec(command1);
            BufferedReader input =
               new BufferedReader(
                  new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
               // Escribimos la salida por pantalla, pero ojo,
               // todo ser� escrito por la consola, por lo que
               // si la aplicaci�n fue lanzada desde Xfuzzy, la
               // salida NO es mostrada en el log de �ste, sino
               // en la consola.
               System.out.println(line);
            }
            input.close();
         } catch (Exception err) {
            // Se ha producido un error en la ejecuci�n
            XfvhdlError err5 = new XfvhdlError(25);
            err5.show();
            return;
         }

      }

      // Lanzamos la herramienta de implementaci�n -si procede-
      if (XfvhdlProperties.implementation == true) {
         //No puede haber errores
         if (error.hasErrors()) {
            XfvhdlError err7 = new XfvhdlError(27);
            err7.show();
            return;
         }

         String command1 = new String();
         String command2 = new String();

         //Mostramos un mensaje de informaci�n
         msg2.addMessage("\n\n>>>> Running Xilinx Xflow \n");
         msg2.show();

         //Depende de la herramienta que se haya indicado
         if (XfvhdlProperties
            .synthesisTool
            .equals((String) "XILINX_XST")) {
            command1 =
               "xflow -implement balanced.opt -wd "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + "_implement "
                  + XfvhdlProperties.outputDirectory
                  + "/"
                  + XfvhdlProperties.outputFile
                  + "_synthesis/"
                  + XfvhdlProperties.outputFile
                  + ".ngc";
         } else {
            command1 =
               "xflow -implement balanced.opt �wd "
                  + XfvhdlProperties.outputFile
                  + "_implement "
                  + XfvhdlProperties.outputFile
                  + "_synthesis/FLC.edf";
         }

         command2 =
            "xflow -config bitgen.opt -wd "
               + XfvhdlProperties.outputDirectory
               + "/"
               + XfvhdlProperties.outputFile
               + "_implement "
               + XfvhdlProperties.outputDirectory
               + "/"
               + XfvhdlProperties.outputFile
               + "_implement/"
               + XfvhdlProperties.outputFile
               + ".ncd";

         // El siguiente comentario ejecutaba sin mostrar la salida
         /*
         	try {
         		msg2.addMessage("\n Executing...<" + command1 + ">");
         		msg2.show();
         		obj.exec(command1);
         
                //Mostramos un mensaje de informaci�n
         		msg2.addMessage(
         			"\n\n>>>> Running FPGA configuration " + "phase \n");
         		msg2.show();
         
                msg2.addMessage("\n Executing...<" + command2 + ">");
         		msg2.show();
         		obj.exec(command2);
         		} catch (Exception e) {
         			XfvhdlError err5 = new XfvhdlError(25);
         			err5.show();
         			return;
         		}
         */
         try {
            String line;
            msg2.addMessage("\n Executing...<" + command1 + ">");
            msg2.show();
            Process p = Runtime.getRuntime().exec(command1);
            BufferedReader input =
               new BufferedReader(
                  new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
               System.out.println(line);
            }
            input.close();
         } catch (Exception err) {
            XfvhdlError err5 = new XfvhdlError(25);
            err5.show();
            return;
         }

         try {
            String line;
            msg2.addMessage("\n Executing...<" + command2 + ">");
            msg2.show();
            Process p = Runtime.getRuntime().exec(command2);
            BufferedReader input =
               new BufferedReader(
                  new InputStreamReader(p.getInputStream()));
            while ((line = input.readLine()) != null) {
               System.out.println(line);
            }
            input.close();
         } catch (Exception err) {
            XfvhdlError err5 = new XfvhdlError(25);
            err5.show();
            return;
         }

      }

      // Termina la aplicaci�n.
      // System.exit(0);	
   }

} // FIN DE LA CLASE Xfvhdl.
